﻿using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using FirstFloor.ModernUI.Windows.Controls;
using Microsoft.Win32;
using Uinside.CreditSystem.DomainModels.Models;
using Uinside.CreditSystem.Services;
using Uinside.CreditSystem.WPF.Tools;
using Uinside.CreditSystem.WPF.Windows;
using Image = Uinside.CreditSystem.DomainModels.Models.Image;

namespace Uinside.CreditSystem.WPF.ViewModels
{
    public class OrdersWorkspaceVIewMode : ViewModelBase
    {
        public virtual bool IsCompany
        {
            get { return false; }
        }

        public override void Dispose()
        {
            if (_creditContext != null)
                _creditContext.Dispose();
            base.Dispose();
        }

        CreditContext _creditContext = new CreditContext();
        private CustomerService _customerService;
        public CustomerService CustomerService
        {
            get
            {
                if (_customerService == null)
                {
                    _customerService = new CustomerService(_creditContext);
                }
                return _customerService;
            }
        }

        private BanksService _banksServiceService;
        public BanksService BanksService
        {
            get
            {
                if (_banksServiceService == null)
                {
                    _banksServiceService = new BanksService(_creditContext);
                }
                return _banksServiceService;
            }
        }

        private PaymentTypeService _paymentTypeService;
        public PaymentTypeService PaymentTypeService
        {
            get
            {
                if (_paymentTypeService == null)
                {
                    _paymentTypeService = new PaymentTypeService(_creditContext);
                }
                return _paymentTypeService;
            }
        }

        private PaymentStatusService _paymentStatusService;
        public PaymentStatusService PaymentStatusService
        {
            get
            {
                if (_paymentStatusService == null)
                {
                    _paymentStatusService = new PaymentStatusService(_creditContext);
                }
                return _paymentStatusService;
            }
        }

        private BankAccountStatusService _bankAccountStatusService;
        public BankAccountStatusService BankAccountStatusService
        {
            get
            {
                if (_bankAccountStatusService == null)
                {
                    _bankAccountStatusService = new BankAccountStatusService(_creditContext);
                }
                return _bankAccountStatusService;
            }
        }

        private OrderStatusService _orderStatusService;
        public OrderStatusService OrderStatusService
        {
            get
            {
                if (_orderStatusService == null)
                {
                    _orderStatusService = new OrderStatusService(_creditContext);
                }
                return _orderStatusService;
            }
        }

        private OrderService _orderService;
        public OrderService OrderService
        {
            get
            {
                if (_orderService == null)
                {
                    _orderService = new OrderService(_creditContext);
                }
                return _orderService;
            }
        }

        private PaymentService _paymentService;
        public PaymentService PaymentService
        {
            get
            {
                if (_paymentService == null)
                {
                    _paymentService = new PaymentService(_creditContext);
                }
                return _paymentService;
            }
        }

        private Setting alreadyPayStatement;
        private ObservableCollection<Order> _collection;
        public ObservableCollection<Order> Collection
        {
            get
            {
                if (_collection == null)
                {
                    RunBackgroundWorker((s, e) =>
                    {
                        SetBusyState(true);
                        alreadyPayStatement = PaymentStatusService.GetAll().First(i => i.Value == 2);
                        _collection = new ObservableCollection<Order>(OrderService.GetAll());
                    }, (s, e) =>
                    {
                        SetBusyState(false);
                        OnPropertyChanged("Collection");

                    });
                }
                return _collection;
            }
        }


        private Order _currentItem;
        public virtual Order CurrentItem
        {
            get
            {
                return _currentItem;
            }
            set
            {
                _currentItem = value;
                OnPropertyChanged("CurrentItem");
            }
        }

        private RelayCommand<object> _saveCommand;
        public RelayCommand<object> SaveCommand
        {
            get
            {
                if (_saveCommand == null)
                    _saveCommand = new RelayCommand<object>(SaveAction, CanSave);
                return _saveCommand;
            }
        }

        private bool CanSave(object obj)
        {
            return true;
        }

        private void SaveAction(object obj)
        {
            SetBusyState(true);
            RunBackgroundWorker((s, e) =>
            {
                _creditContext.SaveChanges();
            }, (s, e) =>
            {
                SetBusyState(false);
                var dialog = new ModernDialog()
                {
                    Content = "保存成功",
                    Height = 50
                };
                dialog.ShowDialog();
            });
        }

        private RelayCommand<object> _deleteCommand;
        public RelayCommand<object> DeleteCommand
        {
            get
            {
                if (_deleteCommand == null)
                    _deleteCommand = new RelayCommand<object>(DeleteAction, CanDelete);
                return _deleteCommand;
            }
        }

        private bool CanDelete(object obj)
        {
            return true;
        }

        private void DeleteAction(object obj)
        {
            _creditContext.Orders.Remove(CurrentItem);
            _creditContext.SaveChanges();
            Collection.Remove(CurrentItem);
        }

        private RelayCommand<object> _addCommand;
        public RelayCommand<object> AddCommand
        {
            get
            {
                if (_addCommand == null)
                    _addCommand = new RelayCommand<object>(AddAction, CanAdd);
                return _addCommand;
            }
        }

        private bool CanAdd(object obj)
        {
            return true;
        }

        private void AddAction(object obj)
        {
            var order = new Order();
            order.StatusId = OrderStatusService.GetAll().First(i => i.Value == 0).Id;
            order.BorrowerId = CustomerService.GetCompany().Id;
            order.LenderId = 0;
            order.CreateDate = DateTime.Now;
            order.OrderNumber = OrderService.GetOrderNumber();

            this.Collection.Add(order);
            this._creditContext.Orders.Add(order);
            CurrentItem = order;
        }

        private RelayCommand<object> _uploadLogoCommand;
        public RelayCommand<object> UploadLogoCommand
        {
            get
            {
                if (_uploadLogoCommand == null)
                    _uploadLogoCommand = new RelayCommand<object>(UploadLogoAction, CanUploadLogo);
                return _uploadLogoCommand;
            }
        }

        private bool CanUploadLogo(object obj)
        {
            return true;
        }

        private void UploadLogoAction(object obj)
        {
            var FileDialog = new OpenFileDialog
            {
                Title = "选择图片",
                InitialDirectory = System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
                Filter = "Image Files (*.gif,*.jpg,*.jpeg,*.bmp,*.png)|*.gif;*.jpg;*.jpeg;*.bmp;*.png",
                FilterIndex = 1
            };
            //CurrentItem.CompanyLogo
            if (FileDialog.ShowDialog() != true) return;
            SetBusyState(true);
            RunBackgroundWorker((s, e) =>
            {

                _creditContext.SaveChanges();
            }, (s, e) =>
            {
                SetBusyState(false);
            });
        }

        private RelayCommand<object> _createDetailCommand;
        public RelayCommand<object> CreateDetailCommand
        {
            get
            {
                if (_createDetailCommand == null)
                    _createDetailCommand = new RelayCommand<object>(CreateDetail, CanCreateDetail);
                return _createDetailCommand;
            }
        }

        private bool CanCreateDetail(object obj)
        {
            return true;
        }

        private void CreateDetail(object obj)
        {
            if (CurrentItem.Payments == null)
                CurrentItem.Payments = new ObservableCollection<Payment>();
            //1.打款
            var deposit = new Payment();
            deposit.TypeId = PaymentTypeService.GetAll().First(i => i.Value == 5).Id;
            deposit.BorrowerId = CurrentItem.BorrowerId;
            deposit.LenderId = CurrentItem.LenderId;
            deposit.StatusId = PaymentStatusService.GetAll().First(i => i.Value == 1).Id;
            deposit.RemindDate = DateTime.Now;
            deposit.ExpectDate = DateTime.Now;
            deposit.PaymentDate = null;
            deposit.Sum = CurrentItem.SumOfLoan;
            CurrentItem.Payments.Add(deposit);


            //一次性还完
            if (CurrentItem.ReturnInterestType == 0)
            {
                var returnPayment = new Payment
                {
                    TypeId = PaymentTypeService.GetAll().First(p => p.Value == 3).Id,
                    BorrowerId = CurrentItem.BorrowerId,
                    LenderId = CurrentItem.LenderId,
                    StatusId = PaymentStatusService.GetAll().First(p => p.Value == 1).Id,
                    RemindDate = CurrentItem.ReturnDate.AddDays(-CurrentItem.PriorToRemind),
                    ExpectDate = CurrentItem.ReturnDate,
                    PaymentDate = null
                };
                returnPayment.Sum = CurrentItem.SumOfLoan * (decimal)(CurrentItem.InterestRatePerDay
                    * (CurrentItem.ReturnDate - CurrentItem.CreateDate).Days);
                CurrentItem.Payments.Add(returnPayment);
            }
            else
            {
                var dateSpan = DateTimeSpan.CompareDates(CurrentItem.CreateDate, CurrentItem.ReturnDate);
                var beginDate = CurrentItem.CreateDate;
                for (int i = 1; i <= dateSpan.Months + dateSpan.Years * 12; i++)
                {
                    var returnPayment = new Payment
                    {
                        TypeId = PaymentTypeService.GetAll().First(p => p.Value == 3).Id,
                        BorrowerId = CurrentItem.BorrowerId,
                        LenderId = CurrentItem.LenderId,
                        StatusId = PaymentStatusService.GetAll().First(p => p.Value == 1).Id,
                        RemindDate = CurrentItem.CreateDate.AddMonths(i).AddDays(-CurrentItem.PriorToRemind),
                        ExpectDate = CurrentItem.CreateDate.AddMonths(i),
                        PaymentDate = null
                    };
                    returnPayment.Sum = CurrentItem.SumOfLoan * (decimal)(CurrentItem.InterestRatePerDay
                        * (returnPayment.ExpectDate - beginDate).Days);
                    CurrentItem.Payments.Add(returnPayment);
                    beginDate = beginDate.AddMonths(1);
                }

                if (CurrentItem.ReturnDate > beginDate)
                {
                    var returnPayment = new Payment
                    {
                        TypeId = PaymentTypeService.GetAll().First(p => p.Value == 3).Id,
                        BorrowerId = CurrentItem.BorrowerId,
                        LenderId = CurrentItem.LenderId,
                        StatusId = PaymentStatusService.GetAll().First(p => p.Value == 1).Id,
                        RemindDate = CurrentItem.ReturnDate.AddDays(-CurrentItem.PriorToRemind),
                        ExpectDate = CurrentItem.ReturnDate,
                        PaymentDate = null,
                        Sum =
                            CurrentItem.SumOfLoan *
                            (decimal)
                                (CurrentItem.InterestRatePerDay * (CurrentItem.ReturnDate - beginDate).Days)
                    };
                    CurrentItem.Payments.Add(returnPayment);
                }
            }
        }


        private RelayCommand<object> _deleteDetailCommand;
        public RelayCommand<object> DeleteDetailCommand
        {
            get
            {
                if (_deleteDetailCommand == null)
                    _deleteDetailCommand = new RelayCommand<object>(DeleteDetail, CanDeleteDetail);
                return _deleteDetailCommand;
            }
        }

        private bool CanDeleteDetail(object obj)
        {
            return true;
        }

        private void DeleteDetail(object obj)
        {
            PaymentService.Delete(CurrentItem.Payments);
            RunBackgroundWorker((s, e) =>
            {
                SetBusyState(true);
                _creditContext.SaveChanges();
            }
                , (s, e) =>
                {
                    SetBusyState(false);
                });
        }


        private RelayCommand<Payment> _confirmPaymentCommand;
        public RelayCommand<Payment> ConfirmPaymentCommand
        {
            get
            {
                if (_confirmPaymentCommand == null)
                    _confirmPaymentCommand = new RelayCommand<Payment>(ConrimPayment, CanConfirmPayment);
                return _confirmPaymentCommand;
            }
        }

        

        private bool CanConfirmPayment(Payment obj)
        {
            if (obj == null || alreadyPayStatement == null)
                return false;

            return obj.StatusId != alreadyPayStatement.Id;
        }

        private void ConrimPayment(Payment obj)
        {
            RunBackgroundWorker((s, e) =>
            {
                SetBusyState(true);
                obj.StatusId = PaymentStatusService.GetAll().First(i => i.Value == 2).Id;
                var depositType = PaymentTypeService.GetAll().First(i => i.Value == 5);
                var returnInterest = PaymentTypeService.GetAll().First(i => i.Value == 3);
                //如果是打款
                if (obj.Type.Id == depositType.Id)
                {
                    obj.Borrower.Capital -= obj.Sum;
                }
                else if (obj.Type.Id == returnInterest.Id)
                {
                    obj.Borrower.Capital += obj.Sum;
                }

                _creditContext.SaveChanges();
            }
                , (s, e) =>
                {
                    SetBusyState(false);
                });
        }

        private RelayCommand<Order> _refreshCommand;
        public RelayCommand<Order> RefreshCommand
        {
            get
            {
                if (_refreshCommand == null)
                    _refreshCommand = new RelayCommand<Order>(Refesh, CanRefesh);
                return _refreshCommand;
            }
        }

        private bool CanRefesh(Order obj)
        {
            return true;
        }

        private void Refesh(Order obj)
        {
            _creditContext.Entry(obj).Reload();
        }
    }
}
